﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CloverNet.Authorization
{
    public class DefaultValidtorProvider : IValidatorProvider
    {
        internal static DefaultValidtorProvider _instance;

        public static DefaultValidtorProvider Current
        {
            get => _instance ?? new DefaultValidtorProvider();
            set => _instance = value;
        }

        public virtual bool ValidatePermission(ActionDescriptor actionDescriptor)
        {
            PermissionStatus PermissionStatus = ValidatePermissionAttribute(actionDescriptor);

            if (PermissionStatus == PermissionStatus.Unknown)
            {
                PermissionStatus= ValidatePermissionAttribute(actionDescriptor.ControllerDescriptor);
            }

            return PermissionStatus == PermissionStatus.Granted;
        }

        protected virtual PermissionStatus ValidatePermissionAttribute(ICustomAttributeProvider attributeProvider)
        {
            IPermissionAttribute permissionAttribute = attributeProvider.GetCustomAttributes(typeof(IPermissionAttribute), false)?.FirstOrDefault() as IPermissionAttribute;

            if (permissionAttribute == null)
            {
                return PermissionStatus.Unknown;
            }

            if (permissionAttribute.Permissions == null)
            {
                return PermissionStatus.Declined;
            }

            object[] userPermissions = DefaultStorageProvider.Current.GetValue(AuthorizationManager.UserAuthStorageKey) as object[];

            if (userPermissions == null)
            {
                return PermissionStatus.Declined;
            }

            var contain =  Enumerable.Intersect(userPermissions, permissionAttribute.Permissions).Any();

            return contain ? PermissionStatus.Granted : PermissionStatus.Declined;
        }

        bool IValidatorProvider.ValidatePermission(ActionDescriptor actionDescriptor)
        {
            return Current.ValidatePermission(actionDescriptor);
        }
    }
}
